home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 8 code / AUX Hybrid Apps / AUX System Calls / src / auxsystem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-09  |  3.9 KB  |  159 lines  |  [TEXT/tefi]

  1.  
  2. #include <LibAUX.h>
  3. #include </:usr:include:sys:errno.h>
  4. #include </:usr:include:sys:signal.h>
  5. #include </:usr:include:fcntl.h>
  6. #include <StdIO.h>
  7. #include <Memory.h>
  8. #include <CursorCtl.h>
  9.  
  10. #define AUXNL (char) '\012'
  11. #define MACOSRET (char) '\015'
  12.  
  13.  
  14. #define    STACKSIZE 2048
  15.  
  16. pascal long     AUXDispatch(selector,p)
  17. short           selector;
  18. char            *p;
  19. extern        0xABf9;
  20.  
  21. #define AUX_GET_ENVIRON 11              /* get pointer to environ */
  22.  
  23. static sigfunc_t cstat, istat, qstat, mstat, signal();
  24. static char *childstack;
  25. static int pid, pipefd_stdout[2], pipefd_stderr[2];
  26.  
  27.  
  28. int
  29. auxsystem(s)
  30. char    *s;
  31. {
  32.     int    status,n, **fake=((int *)&s)+1;
  33.     int GetAUXErrno(), AUXisRunning(), mysigint();
  34.     char *malloc();
  35.     char **auxenviron;
  36.     
  37.     if (!AUXisRunning())
  38.     {
  39.         printf("A/UX is not running \n");
  40.         return(-1);
  41.     }
  42.     
  43.     childstack = NewPtr(STACKSIZE);
  44.     
  45.     /* copy the environment */
  46.     AUXDispatch(AUX_GET_ENVIRON,(char *)&auxenviron);
  47.     
  48.     if (auxpipe(pipefd_stdout) == -1  ||  auxpipe(pipefd_stderr) == -1)
  49.     {
  50.         (void)printf("Error in creating pipes %d \n", GetAUXErrno());
  51.         return(-1);
  52.     }
  53.     
  54.     cstat = auxsignal(SIGCLD, SIG_DFL);
  55.     istat = auxsignal(SIGINT, SIG_IGN);
  56.     qstat = auxsignal(SIGQUIT, SIG_IGN);
  57.     mstat = signal(SIGINT, mysigint); /* this is MPW's signal handler */
  58.  
  59.     if((pid = auxfork(childstack+STACKSIZE,fake)) == 0) {
  60.         if (auxclose(1) == -1)
  61.             return(-1);
  62.         (void)auxdup(pipefd_stdout[1]);
  63.         if (auxclose(2) == -1)
  64.             return(-1);
  65.         (void)auxdup(pipefd_stderr[1]);
  66.         if ((auxclose(pipefd_stdout[0]) == -1) ||
  67.             (auxclose(pipefd_stdout[1]) == -1)) return(-1);
  68.         if ((auxclose(pipefd_stderr[0]) == -1) ||
  69.             (auxclose(pipefd_stderr[1]) == -1)) return(-1);
  70.         pid = auxgetpid();
  71.         (void) auxsetpgrp(pid,pid);
  72.         (void) auxexecl("/bin/sh", "sh", "-c", s, 0);
  73.         aux_exit(127);
  74.     }
  75.     else {
  76.         if (pid < 0) {
  77.             (void)auxclose(pipefd_stdout[0]);
  78.             (void)auxclose(pipefd_stdout[1]);
  79.             (void)auxclose(pipefd_stderr[0]);
  80.             (void)auxclose(pipefd_stderr[1]);
  81.             (void) auxsignal(SIGCLD, cstat);
  82.             (void) auxsignal(SIGINT, istat);
  83.             (void) auxsignal(SIGQUIT, qstat);
  84.             (void) signal(SIGINT, mstat);
  85.             DisposPtr((char *)childstack);    /* Fork failed */
  86.             return(-1);
  87.         }
  88.         else {
  89.             char    *cp, buf[1024];
  90.             long    cnt;
  91.             int flags,out,err;
  92.  
  93.             flags = auxfcntl(pipefd_stdout[0],F_GETFL,0);
  94.             (void)auxfcntl(pipefd_stdout[0],F_SETFL,flags | O_NONBLOCK);
  95.             (void)auxclose(pipefd_stdout[1]);
  96.             flags = auxfcntl(pipefd_stderr[0],F_GETFL,0);
  97.             (void)auxfcntl(pipefd_stderr[0],F_SETFL,flags | O_NONBLOCK);
  98.             (void)auxclose(pipefd_stderr[1]);
  99.  
  100.             for ( out=err=1; out || err; ) {
  101.                 if ( out ) cnt = auxread(pipefd_stdout[0],buf,1024);
  102.                 else cnt = 0;
  103.                 if ( cnt > 0 ) {
  104.                     buf[cnt] = '\0';
  105.                     while ( cp = (char *)strchr(buf,AUXNL) )
  106.                         *cp = MACOSRET;
  107.                     (void)write(fileno(stdout), buf, cnt);
  108.                 }
  109.                 else {
  110.                     if ( cnt == 0 ) out = 0;
  111.                     if ( err ) cnt = auxread(pipefd_stderr[0],buf,1024);
  112.                     else cnt = 0;
  113.                     if ( cnt > 0 ) {
  114.                         buf[cnt] = '\0';
  115.                         while ( cp = (char *)strchr(buf,AUXNL) )
  116.                             *cp = MACOSRET;
  117.                         (void)write(fileno(stderr), buf, cnt);
  118.                     }
  119.                     else if ( cnt == 0 ) err = 0;                        SpinCursor(1);
  120.                 };
  121.                 SpinCursor(1);
  122.             };
  123.             
  124.             for ( status=n=0; n!=pid; n=auxwait(&status) ) 
  125.                 if ( n<0 && GetAUXErrno()!=EINTR ) break;
  126.                 
  127.             auxclose(pipefd_stdout[0]);
  128.             auxclose(pipefd_stderr[0]);
  129.  
  130.             (void) auxsignal(SIGCLD, cstat);
  131.             (void) auxsignal(SIGINT, istat);
  132.             (void) auxsignal(SIGQUIT, qstat);
  133.             (void) signal(SIGINT, mstat);
  134.             DisposPtr((char *)childstack);
  135.             return(status);
  136.         }
  137.     }
  138. }
  139.  
  140. mysigint()
  141. {
  142.     int status,n;
  143.     
  144.     if ( pid > 0 ) {
  145.         (void) auxkill(-pid,SIGKILL);
  146.         for ( status=n=0; n!=pid; n=auxwait(&status) ) 
  147.             if ( n<0 && GetAUXErrno()!=EINTR ) break;
  148.     };
  149.     auxclose(pipefd_stdout[0]);
  150.     auxclose(pipefd_stderr[0]);
  151.     (void) auxsignal(SIGCLD, cstat);
  152.     (void) auxsignal(SIGINT, istat);
  153.     (void) auxsignal(SIGQUIT, qstat);
  154.     (void) signal(SIGINT, mstat);
  155.     DisposPtr((char *)childstack);
  156.     printf("Unixcmd execution terminated by user interrupt\n");
  157.     exit(-1);
  158. }
  159.